/*********************************************************************************
 *      Copyright:  (C) 2019 Wu Yujun<540726307@qq.com>
 *                  All rights reserved.
 *
 *       Filename:  gsmd.c
 *    Description:  This file check gsm module regiter or not
 *                 
 *        Version:  1.0.0(2019年06月30日)
 *         Author:  Wu Yujun <540726307@qq.com>
 *      ChangeLog:  1, Release initial version on "2019年06月30日 12时14分13秒"
 *                 
 ********************************************************************************/
#include <stdio.h>
#include <string.h>
#include <errno.h>


#include "comport.h"
#include "gsmd.h"
#include "at_cmd.h"
#include "ppp.h"



/*******************************************************************
 *  描述： 检查程序是否在运行
 *
 *  参数： const char *program_name程序名
 *
 *  返回值：
 *      检查失败返回负数，程序还在运行返回Running, 程序退出了返回Exit
 ************************************************************************/
int check_program_running(const char *program_name)
{
    char    check_cmd[128] ;
    char    check_file[64] ;
    int     fd = -1 ; 
    char    buf[256] ;
    int     rv = -1 ;
    
    if(!program_name)
    {
        printf("Invail parameter input in %s\n",__FUNCTION__);
        rv =  -1 ;
        goto cleanup ;
    }
    snprintf(check_file, sizeof(check_file),"%s_process.txt", program_name) ;
    /* 将命令重定向到文件查看文件是否还在运行 */
    snprintf(check_cmd, sizeof(check_cmd), "ps | grep -v grep | grep %s > %s",program_name, check_file ) ; 
    system(check_cmd) ;
    fd = open(check_file, O_RDONLY) ;
    if(fd < 0)
    {
        printf("Open %s error:%s\n", check_file, strerror(errno)) ;
        rv = -2 ;
        goto cleanup ;
    }
    memset(buf, 0 , sizeof(buf)) ;
    rv = read(fd, buf, sizeof(buf)) ;
    if(rv < 0)
    {
        printf("Read from %s error: %s\n",program_name ,strerror(errno)) ;
        rv =  -3 ;
        goto cleanup ;
    }
    /* 读出来后删除文件防止资源浪费 */
    rv = remove(check_file) ;
    if(rv < 0)
    {
        printf("Remove %s fail:%s\n",check_file, strerror(errno));
        rv = -4 ;
        goto cleanup ;
    }
    if(strstr(buf, program_name))
    {
#if 0
        printf("%s is Running\n", program_name);
#endif
        rv = Running ;
    }
    else
    {
#if 0
        printf("%s is already exit\n", program_name) ;
#endif
        rv = Exit ;
    }

cleanup :
    return rv ;
}


/****************************************************************
 *  描述： 初始化gsmd结构体
 *
 *  参数：
 *      port服务器用于监听的端口
 *  返回值：
 *      成功返回malloc分配的指向gsmd结构体的指针，失败返回NULL
 *
 ***************************************************************/
st_gsmd_ctx* init_gprs_module(int port) 
{
    st_gsmd_ctx     *gsmd_ctx = NULL;
    int             rv = -1 ;

    
    if((!port)||(port < 1024))
    {
        printf("Invail input paremeter in %s\n", __FUNCTION__) ;
        return NULL ;
    }
    gsmd_ctx = malloc(sizeof(st_gsmd_ctx)) ;
    if(!gsmd_ctx ) //堆区分配完了
    {
        printf("malloc failed in %s:%s\n",__FUNCTION__, strerror(errno)) ;
        return NULL ;
    }

    memset(gsmd_ctx, 0, sizeof(gsmd_ctx)) ;
    /*  初始化gsmSocket   */
    gsmd_ctx->gsmSocket.fd = -1 ;
    gsmd_ctx->gsmSocket.cli_fd = -1 ;
    gsmd_ctx->gsmSocket.port = port ;

    /* 初始化worker */
    pthread_mutex_init(&(gsmd_ctx->worker.lock), NULL);
    gsmd_ctx->worker.PPP = OFF ;
    gsmd_ctx->worker.status = FREE ;
    rv = check_program_running("pppd") ;
    if(rv == Running)
    {
        gsmd_ctx->worker.PPP = ON ;
        gsmd_ctx->worker.status = BUSY ;
        gsmd_ctx->worker.current = REQ_PPP ;
    }


    /* 初始化gsmRegInfo注册情况 */
    gsmd_ctx->gsmRegInfo.ready = NO ;
    gsmd_ctx->gsmRegInfo.sim_signal = NO_SIGNAL ;
    gsmd_ctx->gsmRegInfo.sim_register = NO_CREG ;


    return gsmd_ctx ;
}




/* ***********************************
 *  描述： 销毁gsmd结构体
 *
 * ************************************/
void destroy_gsmd(st_gsmd_ctx *gsmd_ctx)
{

    if(!gsmd_ctx)
    {
        return ;
    }
    if(gsmd_ctx -> worker.PPP == ON)
    {
        close_ppp(Data_COM) ;
    }
    sleep(1) ;
    memset(gsmd_ctx, 0 , sizeof(st_gsmd_ctx)) ;
    free(gsmd_ctx) ;
    gsmd_ctx = NULL ;
}



/********************************************
 *  描述：根据检查模块注册情况的返回值进行休眠
 *
 ********************************************/
void gsmd_sleep(int reval)
{
    switch(reval)
    {
        case OPEN_ERROR:
            sleep(10) ;
            break ;
        case NOT_IN:
            sleep(8) ;
            break ;
        case NO_SIGNAL:
            sleep(5) ;
            break ;
        case ERROR_IMSI:
            sleep(4) ;
            break ;
        case NO_CREG:
            sleep(3) ;
            break ;
        default:
            break ;
    }
}
